﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	SharePointExts.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.UI;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using Smart.Common.Entities;

namespace Smart.Common
{
	[Localizable(false), DebuggerStepThrough]
	public static class SharePointExts
	{
		public static SPLongOperation SetTrailingWithSpan(this SPLongOperation lo, string trailing)
		{
			if (lo != null)
				lo.TrailingHTML = "<span id=\"tspan\">" + trailing + "</span>";

			return lo;
		}

		public static SPLongOperation SetLeadingWithSpan(this SPLongOperation lo, string leading)
		{
			if (lo != null)
				lo.LeadingHTML = "<span id=\"lspan\">" + leading + "</span>";

			return lo;
		}

		public static SPLongOperation SetDynamicTrailing(this SPLongOperation lo, string trailing)
		{
			if (lo != null)
			{
				HttpContext.Current.Response.Write("<script language=\"javascript\">tspan.innerHTML = \"" + trailing.EncodeJS("\"").Replace(Environment.NewLine, "<br/>") + "\";</script>");
				HttpContext.Current.Response.Flush();
				HttpContext.Current.Response.Write("<!-- flush -->");
				HttpContext.Current.Response.Flush();
			}

			return lo;
		}

		public static SPLongOperation SetDynamicLeading(this SPLongOperation lo, string leading)
		{
			if (lo != null)
			{
				HttpContext.Current.Response.Write("<script language=\"javascript\">lspan.innerHTML = \"" + leading.EncodeJS("\"").Replace(Environment.NewLine, "<br/>") + "\";</script>");
				HttpContext.Current.Response.Flush();
				HttpContext.Current.Response.Write("<!-- flush -->");
				HttpContext.Current.Response.Flush();
			}

			return lo;
		}

		public static string IncapsulateSP(this string value)
		{
			return value == null ? null : value.EncodeXml();
		}

		public static string IncapsulateSP(this DateTime value)
		{
			return value.IsEmpty() ? null : SPUtility.CreateISO8601DateTimeFromSystemDateTime(value);
		}

		public static string IncapsulateSP(this Guid value)
		{
			return value.IsEmpty() ? null : value.ToString("D");
		}

		public static string IncapsulateSP(this object value)
		{
			if (value == null)
				return null;

			var svalue = value as string;
			if (svalue != null)
				return IncapsulateSP(svalue);
			if (value is DateTime)
				return IncapsulateSP((DateTime)value);
			if (value is int)
				return ((int)value).ToString(H.En);
			if (value is double)
				return ((double)value).ToString(H.En);
			if (value is float)
				return ((float)value).ToString(H.En);
			if (value is decimal)
				return ((decimal)value).ToString(H.En);
			if (value is Guid)
				return IncapsulateSP((Guid)value);
			if (value is char)
				return IncapsulateSP(new string((char)value, 1));

			return IncapsulateSP(value.ToString());
		}

		/// <summary>
		/// Return item field values
		/// </summary>
		public static void GetTaskValues(this SPWorkflowTaskProperties properties, SPWeb web, SPListItem item, SPListItem task, Dictionary<string, object> fields, IDictionary<string, object> values)
		{
			try
			{
				if (web != null)
				{
					values["WebTitle"] = web.Title;
					values["WebUrl"] = web.Url;
				}

				if (item != null)
				{
					var culture =
						item.Web != null
							? item.Web.UICulture
							: System.Threading.Thread.CurrentThread.CurrentUICulture;

					var dfv = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

					item.GetValues(dfv);

					var ufv = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

					dfv.GetUserValues(ufv, culture);

					foreach (var kvp in ufv)
						values["Item" + kvp.Key] = kvp.Value;

					if (item.FileSystemObjectType == SPFileSystemObjectType.File || item.FileSystemObjectType == SPFileSystemObjectType.Folder)
					{
						values["ItemTitle"] = item.Name ?? item.Title;
					}
					else
					{
						values["ItemTitle"] = item.Title ?? item.Name;
					}

					values["ItemUrl"] = item.Web.Url + item.Url.EnsureStartsWith("/");
					values["ItemDispUrl"] = item.GetItemDispUrl();
					values["ItemContentType"] = (item.ContentType != null ? item.ContentType.Name : string.Empty);
				}

				if (task != null)
				{
					values["Title"] = task.Title;
					values["AssignedTo"] = task.GetStr(SPBuiltInFieldId.AssignedTo).GetPostPartDelimitValue(SPH.LookupValueDelimiter);
					values["Description"] = task.GetStr(SPBuiltInFieldId.Body);
					values["DueDate"] = task.Get(SPBuiltInFieldId.TaskDueDate).SToDT(DateTime.MaxValue).ToShortDateString();
					values["PercentComplete"] = task.GetDbl(SPBuiltInFieldId.PercentComplete).ToString("##0.");
					values["StartDate"] = task.Get(SPBuiltInFieldId.StartDate).SToDT(DateTime.MaxValue).ToShortDateString();
					values["TaskItemId"] = task.ID;
				}
				else if (properties != null)
				{
					values["Title"] = properties.Title;
					values["AssignedTo"] = properties.AssignedTo;
					values["Description"] = properties.Description;
					values["DueDate"] = properties.DueDate.ToShortDateString();
					values["OnBehalfEmail"] = properties.OnBehalfEmail;
					values["OnBehalfReason"] = properties.OnBehalfReason;
					values["PercentComplete"] = properties.PercentComplete.ToString("##0");
					values["StartDate"] = properties.StartDate.ToShortDateString();
					values["TaskItemId"] = properties.TaskItemId;

					if (fields == null)
						return;

					var xp = properties.ExtendedProperties;

					foreach (var field in fields)
					{
						if (xp.ContainsKey(field.Value))
							values[field.Key] = xp[field.Value].SToStr();
					}
				}

				var emptyKeys = values.Where(kvp => kvp.Value == null).Select(kvp => kvp.Key).ToArray();

				foreach (var emptyKey in emptyKeys)
					values[emptyKey] = string.Empty;
			}
			catch (Exception x)
			{
				H.LX("GetTaskValues", x);
			}
		}

		/// <summary>
		/// Redirect Or Close Current Page
		/// </summary>
		public static void RedirectOrClose(this Page page, string sourceUrl, bool closeIfEmpty)
		{
			if (!SPContext.Current.IsPopUI)
			{
				if (!sourceUrl.IsNullOrEmpty() || !closeIfEmpty)
				{
					SPUtility.Redirect(sourceUrl, SPRedirectFlags.UseSource, HttpContext.Current);
				}
				else
				{
					page.Response.Write("<script type='text/javascript'>window.close();</script>");

					page.Response.Flush();
					page.Response.End();
				}
			}
			else
			{
				page.Response.Write("<script type='text/javascript'>window.frameElement.commitPopup();</script>");

				page.Response.Flush();
				page.Response.End();
			}
		}

		/// <summary>
		/// Checks whether Workflow in running state
		/// </summary>
		public static bool IsInRunningState(this SPWorkflow wf)
		{
			if (wf == null)
				return false;

			return
				((wf.InternalState & SPWorkflowState.Running) == SPWorkflowState.Running);
		}
	}
}